package org.vison.wonfu.framework.soa;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.vison.wonfu.framework.commons.Constants;
import org.vison.wonfu.framework.config.utils.PropertyConfigurer;

/**
 * todo: 可以考虑不用bean,全部用静态方法
 * SOA框架的配置属性类
 * 1. 手动降级开关是否开启
 * 2. 熔断是否开启
 * 3. 滑动窗口大小（单位：秒）
 * 4. 成功阈值
 * 5. 半开检测期（单位：秒）
 * 6. 请求阈值
 */
@Component
public class SoaPropertys {

    private static final Logger logger = LoggerFactory.getLogger(SoaPropertys.class);

    /**
     * 手动降级开关是否开启
     * 1. 优先使用application的配置
     * 2. 如果application没有配置，则使用统一的wonfu.governance下的配置开关
     * @param key
     * @return
     */
    public boolean isConsumerMethodManualBreakerOpen(String key){
        String configKey = SoaConstants.CIRCLE_BREAKER_MANUAL_BREAKER+key;
        Boolean configSwitch = PropertyConfigurer.getBoolean(configKey,null);
        if(configSwitch == null){
            configSwitch = PropertyConfigurer.getBoolean(Constants.GOVERNANCE_NAMESPACE,
                    SoaConstants.CIRCLE_BREAKER_MANUAL_BREAKER+key,
                    SoaConstants.DEFAULT_CIRCLE_BREAKER_MANUAL_BREAKER);
        }
        if(configSwitch){
            logger.info("手动降级开关开启，key:{}",configKey);
        }
        return configSwitch;
    }
    
    /**
     * 熔断是否开启
     * 1. 优先使用application的配置
     * 2. 如果application没有配置，则使用统一的wonfu.governance下的配置开关
     * @param key
     * @return
     */
    public boolean isConsumerMethodBreakerEnabled(String key){
        String configKey = SoaConstants.CIRCLE_BREAKER_ENABLE+key;
        Boolean configSwitch = PropertyConfigurer.getBoolean(configKey,null);
        if(configSwitch == null){
            configSwitch = PropertyConfigurer.getBoolean(Constants.GOVERNANCE_NAMESPACE,
                    SoaConstants.CIRCLE_BREAKER_ENABLE+key,
                    SoaConstants.DEFAULT_CIRCLE_BREAKER_ENABLE);
        }
        return configSwitch;
    }
    
    /**
     * 获取指定key的滑动窗口大小（单位：秒）
     * 1. 优先使用application的配置
     * 2. 如果application没有配置，则使用统一的wonfu.governance下的配置
     * @param key
     * @return 默认返回10秒
     */
    public int getConsumerMethodSlidingWindowSize(String key){
        String configKey = SoaConstants.CIRCLE_BREAKER_SLIDING_WINDOW_SIZE+key;
        Integer value = PropertyConfigurer.getInteger(configKey,null);
        if(value == null){
            value = PropertyConfigurer.getInteger(Constants.GOVERNANCE_NAMESPACE,
                    SoaConstants.CIRCLE_BREAKER_SLIDING_WINDOW_SIZE+key,
                    SoaConstants.DEFAULT_CIRCLE_BREAKER_SLIDING_WINDOW_SIZE);
        }
        return value;
    }
    
    /**
     * 获取指定key的半开间隔（单位：秒）
     * 1. 优先使用application的配置
     * 2. 如果application没有配置，则使用统一的wonfu.governance下的配置
     * @param key
     * @return 默认返回5秒
     */
    public int getConsumerMethodHalfOpenInterval(String key){
        String configKey = SoaConstants.CIRCLE_BREAKER_HALF_OPEN_INTERVAL+key;
        Integer value = PropertyConfigurer.getInteger(configKey,null);
        if(value == null){
            value = PropertyConfigurer.getInteger(Constants.GOVERNANCE_NAMESPACE,
                    SoaConstants.CIRCLE_BREAKER_HALF_OPEN_INTERVAL+key,
                    SoaConstants.DEFAULT_CIRCLE_BREAKER_HALF_OPEN_INTERVAL);
        }
        return value;
    }
    
    /**
     * 获取指定key的连续成功次数阈值
     * 1. 优先使用application的配置
     * 2. 如果application没有配置，则使用统一的wonfu.governance下的配置
     * @param key
     * @return 默认返回3次
     */
    public int getConsumerMethodSuccessThreshold(String key){
        String configKey = SoaConstants.CIRCLE_BREAKER_SUCCESS_THRESHOLD+key;
        Integer value = PropertyConfigurer.getInteger(configKey,null);
        if(value == null){
            value = PropertyConfigurer.getInteger(Constants.GOVERNANCE_NAMESPACE,
                    SoaConstants.CIRCLE_BREAKER_SUCCESS_THRESHOLD+key,
                    SoaConstants.DEFAULT_CIRCLE_BREAKER_SUCCESS_THRESHOLD);
        }
        return value;
    }
    
    /**
     * 获取指定key的请求阈值
     * 1. 优先使用application的配置
     * 2. 如果application没有配置，则使用统一的wonfu.governance下的配置
     * @param key
     * @return 默认返回100次
     */
    public int getConsumerMethodRequestThreshold(String key){
        String configKey = SoaConstants.CIRCLE_BREAKER_REQUEST_THRESHOLD+key;
        Integer value = PropertyConfigurer.getInteger(configKey,null);
        if(value == null){
            value = PropertyConfigurer.getInteger(Constants.GOVERNANCE_NAMESPACE,
                    SoaConstants.CIRCLE_BREAKER_REQUEST_THRESHOLD+key,
                    SoaConstants.DEFAULT_CIRCLE_BREAKER_REQUEST_THRESHOLD);
        }
        return value;
    }
    
    /**
     * 获取指定key的错误率阈值
     * 1. 优先使用application的配置
     * 2. 如果application没有配置，则使用统一的wonfu.governance下的配置
     * @param key
     * @return 默认返回0.5（50%）
     */
    public double getConsumerMethodErrorRateThreshold(String key){
        String configKey = SoaConstants.CIRCLE_BREAKER_ERROR_RATE_THRESHOLD+key;
        Double value = PropertyConfigurer.getDouble(configKey,null);
        if(value == null){
            value = PropertyConfigurer.getDouble(Constants.GOVERNANCE_NAMESPACE,
                    SoaConstants.CIRCLE_BREAKER_ERROR_RATE_THRESHOLD+key,
                    SoaConstants.DEFAULT_CIRCLE_BREAKER_ERROR_RATE_THRESHOLD);
        }
        return value;
    }
}